#include "CBattleInf.h"
#include "CBattleBuff.h"
#include "../mainctrl.h"

/************************************************************************/
/*                    CBattleBuff                                       */
/************************************************************************/
void CBattleBuff::NewTurn()
{
    for (int i = 0; i < _aiBuffLast.Size(); )//这里不要递增 放在了逻辑里面
    {
        --_aiBuffLast[i];

        if (_aiBuffLast[i] <= 0)
        {
            _aiBuffLast.DelOneItem(i);
        }
        else
        {
            ++i;
        }
    }
}

void CBattleBuff::SetSrcRoleID(int iSrcID, int iLast)
{
    if (iLast <= 0)
    {
        return;
    }

    int iMaxLast = 0;
    
    for (int i = 0; i < _aiBuffLast.Size(); ++i)
    {
        if (_aiBuffLast[i] > iMaxLast)
        {
            iMaxLast = _aiBuffLast[i];
        }
    }

    if (iLast > iMaxLast)
    {
        _iSrcRoleID = iSrcID;
    }
}

int CBattleBuff::GetMaxTurn()
{
    int iMaxTurn = 0;

    for (int i = 0; i < _aiBuffLast.Size(); ++i)
    {
        if (_aiBuffLast[i] > iMaxTurn)
        {
            iMaxTurn = _aiBuffLast[i];
        }
    }

    return iMaxTurn;
}

void CBattleBuff::AddOneLast(int iLast)
{
    if (iLast <= 0)
    {
        return;
    }

    int iLittle = iLast;
    int iLittleIndex = -1;//下标值初始为负

    if (_aiBuffLast.Size() < _aiBuffLast.GetCount())
    {
        _aiBuffLast.AddOneItem(iLast);
    }
    else
    {
        for (int i = 0; i < _aiBuffLast.Size(); ++i)
        {
            if (_aiBuffLast[i] < iLittle)
            {
                iLittle = _aiBuffLast[i];
                iLittleIndex = i;
            }
        }

        if (iLittleIndex >= 0 && iLittleIndex < _aiBuffLast.Size())
        {
            _aiBuffLast[iLittleIndex] = iLast;
        }
    }
}

void CBattleBuff::SetOneBuff(CSkillEffect& stSkillEffect, int iSrcID)
{
    _iTurn = BATTLE_INF->_pstRoundCtrl->GetRoundNum();
    _iSrcRoleID = iSrcID;
    _stEffect = stSkillEffect;
    AddOneLast(stSkillEffect.GetLastTurnCount());
}

int CBattleBuff::DealShieldBuff(int iRoleID, int& iChgBlood)
{
    int iDataOld = GetData();
    int iDataNow = iDataOld;

    if (iDataOld > 0 && iChgBlood < 0)
    {
        iDataNow += iChgBlood;
        if (iDataNow >= 0)
        {
            iChgBlood = 0;
        }
        else
        {
            iChgBlood += iDataOld;
            iDataNow = 0;
        }
    }

    if (iDataNow != iDataOld)
    {
        SetData(iDataNow);
        BATTLE_INF->_pstVideo->ModShield(iRoleID, iDataNow - iDataOld);
        CT_BATTLE(("角色(%d)护盾初始(%d)减少(%d)剩余(%d)",
            iRoleID, iDataOld, iDataOld - iDataNow, iDataNow));
    }

    return 0;
}

void CBattleBuff::DumpBattleBuff()
{
    CTSizeString<100>  sVideo;
    for (int i = 0; i < _aiBuffLast.Size(); ++i)
    {
        sVideo.Cat("%d ",_aiBuffLast[i]);
    }

    CT_BATTLE(("效果(%u)获得回合(%d)层数(%d)释放者(%d)叠加序列(%s)",
               GetID(),GetTurn(),GetLastSize(),GetSrcRoleID(),sVideo.Get()));
}

/************************************************************************/
/*                    CBattleBuffList                                   */
/************************************************************************/
int CBattleBuffList::GetFrontIndex(int iSrcType, int iIndex)
{
    if (BATTLE_BUFF_SOURCE_SELF != iSrcType &&
        BATTLE_BUFF_SOURCE_TEAM != iSrcType &&
        BATTLE_BUFF_SOURCE_ENEMY != iSrcType)
    {
        CT_ERROR(("battle buff source type(%d) error",iSrcType));
        return 0;
    }

    return (MAX_BATTLE_BUFF_COUNT *(iSrcType - 1) + iIndex);
}

void CBattleBuffList::RoleAddBuffVideo(int iRoleID, unsigned int uiEffectID,
        int iSrcType, int iSrcID, int iTurn, int iAddNum)
{
    //int iFrontIndex = GetFrontIndex(iSrcType, iIndex);

    CT_BATTLE(("角色(%d)中了效果(%u)来源个体类型(%d)释放者(%d)剩余回合数" \
               "(%d)叠加数(%d)",
               iRoleID,uiEffectID,iSrcType,iSrcID,iTurn,iAddNum));

    BATTLE_INF->_pstVideo->AddBuff(iRoleID, iSrcID, uiEffectID, iTurn, iAddNum);
}

void CBattleBuffList::RoleDelBuffVideo(int iRoleID, unsigned int uiEffectID,
        int iSrcType, int iSrcID, int iIndex)
{
    int iFrontIndex = GetFrontIndex(iSrcType, iIndex);

    CT_BATTLE(("角色(%d)消除效果(%u)下标(%d)来源(%d)释放者(%d)",
               iRoleID,uiEffectID,iFrontIndex,iSrcType,iSrcID));

    BATTLE_INF->_pstVideo->BuffExpire(iRoleID, iSrcID, uiEffectID, iFrontIndex);
}

void CBattleBuffList::RoleChgBuffVideo(int iRoleID, unsigned int uiEffectID,
        int iSrcType, int iSrcID, int iIndex)
{
    int iFrontIndex = GetFrontIndex(iSrcType, iIndex);

    CT_BATTLE(("角色(%d)变化效果(%u)下标(%d)来源(%d)释放者(%d)",
               iRoleID,uiEffectID,iFrontIndex,iSrcType,iSrcID));

    //暂时使用增加的命令输出 byronwei_tmp
    //BATTLE_INF->_pstVideo->AddBuff(iRoleID, uiEffectID, iFrontIndex);
}

int CBattleBuffList::AddOneBuff(int iRoleID, CSkillEffect& stSkillEffect,
        int iSrcType, int iSrcID, BATTLE_BUFF_LIST& stBuffList)
{
    int iRet = 0;
    int iOriIndex = -1;//下标值初始为负
    int iOldIndex = -1;//下标值初始为负
    int iOldTurn = BATTLE_INF->_pstRoundCtrl->GetRoundNum();
    int iOldLastSize = 0;

    for (int i = 0; i < stBuffList.Size(); ++i)
    {
        if (stBuffList[i].GetID() == stSkillEffect.GetID())
        {
            iOriIndex = i;
            break;
        }

        if (stBuffList[i].GetTurn() < iOldTurn)
        {
            iOldTurn = stBuffList[i].GetTurn();
            iOldIndex = i;
        }
    }

    //此来源此状态已在角色身上
    if (iOriIndex >= 0 && iOriIndex < stBuffList.Size())
    {
        if (stSkillEffect.IsShield())//护盾类型
        {
            stBuffList[iOriIndex].Clear();
            stBuffList[iOriIndex].SetOneBuff(stSkillEffect, iSrcID);
        }
        else
        {
            iOldLastSize = stBuffList[iOriIndex].GetLastSize();
            
            stBuffList[iOriIndex].SetSrcRoleID(iSrcID,
                stSkillEffect.GetLastTurnCount());
            
            stBuffList[iOriIndex].AddOneLast(stSkillEffect.GetLastTurnCount());
            
            if (stBuffList[iOriIndex].GetLastSize() != iOldLastSize)
            {
                RoleChgBuffVideo(iRoleID, stSkillEffect.GetID(), iSrcType,
                    stBuffList[iOriIndex].GetSrcRoleID(), iOriIndex);
            }
        }
    }

    //此来源此状态不在角色身上且Buff未满
    if (iOriIndex < 0 && stBuffList.Size() < stBuffList.GetCount())
    {
        CBattleBuff stBattleBuff;
        stBattleBuff.SetOneBuff(stSkillEffect, iSrcID);
        iRet = stBuffList.AddOneItem(stBattleBuff);
        if (iRet >= 0)
        {
            RoleAddBuffVideo(iRoleID, stSkillEffect.GetID(), iSrcType,
                stBattleBuff.GetSrcRoleID(), stBattleBuff.GetMaxTurn(),
                stBattleBuff.GetLastSize());
        }
    }

    //此来源此状态不在角色身上但Buff已满且找出剩余回合最少的一个替换
    if (iOriIndex < 0 && iOldIndex >= 0 && iOldIndex < stBuffList.Size())
    {
        CBattleBuff stBattleBuff;
        stBattleBuff.SetOneBuff(stSkillEffect, iSrcID);

        RoleDelBuffVideo(iRoleID, stBuffList[iOldIndex].GetID(), iSrcType,
            stBuffList[iOldIndex].GetSrcRoleID(), iOldIndex);

        stBuffList[iOldIndex] = stBattleBuff;

        RoleAddBuffVideo(iRoleID, stBattleBuff.GetID(), iSrcType,
            stBuffList[iOldIndex].GetSrcRoleID(),
            stBuffList[iOldIndex].GetMaxTurn(),
            stBuffList[iOldIndex].GetLastSize());
    }

    //注意在同一回合内处理超过数组长度的Buff的情况
    if (iOriIndex < 0 && iOldIndex < 0 &&
        stBuffList.Size() >= stBuffList.GetCount())
    {
        CT_BATTLE(("同一回合增加超过数组长度的效果默认去掉第1个"));

        CBattleBuff stBattleBuff;
        stBattleBuff.SetOneBuff(stSkillEffect, iSrcID);

        RoleDelBuffVideo(iRoleID, stBuffList[0].GetID(), iSrcType,
            stBuffList[0].GetSrcRoleID(), 0);

        stBuffList[0] = stBattleBuff;

        RoleAddBuffVideo(iRoleID, stBattleBuff.GetID(), iSrcType,
            stBuffList[0].GetSrcRoleID(),stBuffList[0].GetMaxTurn(),
            stBuffList[0].GetLastSize());
    }

    if (stSkillEffect.IsShield())//护盾类型 额外输出数值
    {
        CT_BATTLE(("角色(%d)中护盾效果(%u)来源类型(%d)释放者(%d)剩余回合数(%d)",
            iRoleID,stSkillEffect.GetID(),iSrcType,iSrcID,
            stSkillEffect.GetLastTurnCount()));
        
        BATTLE_INF->_pstVideo->ModShield(iRoleID, stSkillEffect.GetData());
    }

    return 0;
}

int CBattleBuffList::AddOneBuff(int iRoleID, CSkillEffect& stSkillEffect,
        int iSrcType, int iSrcID)
{
    int iRet = 0;

    if (BATTLE_BUFF_SOURCE_SELF == iSrcType)
    {
        iRet = AddOneBuff(iRoleID, stSkillEffect, iSrcType, iSrcID,
            _astSelfBuff);
    }
    else if (BATTLE_BUFF_SOURCE_TEAM == iSrcType)
    {
        iRet = AddOneBuff(iRoleID, stSkillEffect, iSrcType, iSrcID,
            _astTeamBuff);
    }
    else if (BATTLE_BUFF_SOURCE_ENEMY == iSrcType)
    {
        iRet = AddOneBuff(iRoleID, stSkillEffect, iSrcType, iSrcID,
            _astEnemyBuff);
    }
    else
    {
        CT_ERROR(("role(%d) deal skill effct(%u) unknow source type(%d)",
            iRoleID, stSkillEffect.GetID(),iSrcType));
    }

    return iRet;
}

bool CBattleBuffList::IsSwim()
{
    for (int i = 0; i < _astSelfBuff.Size(); ++i)
    {
        if (_astSelfBuff[i].IsSwim())
        {
            return true;
        }
    }

    for (int i = 0; i < _astTeamBuff.Size(); ++i)
    {
        if (_astTeamBuff[i].IsSwim())
        {
            return true;
        }
    }

    for (int i = 0; i < _astEnemyBuff.Size(); ++i)
    {
        if (_astEnemyBuff[i].IsSwim())
        {
            return true;
        }
    }

    return false;
}

bool CBattleBuffList::IsStick()
{
    for (int i = 0; i < _astSelfBuff.Size(); ++i)
    {
        if (_astSelfBuff[i].IsStick())
        {
            return true;
        }
    }

    for (int i = 0; i < _astTeamBuff.Size(); ++i)
    {
        if (_astTeamBuff[i].IsStick())
        {
            return true;
        }
    }

    for (int i = 0; i < _astEnemyBuff.Size(); ++i)
    {
        if (_astEnemyBuff[i].IsStick())
        {
            return true;
        }
    }

    return false;
}

bool CBattleBuffList::InDefinitBuff(unsigned char ucStatType,
        unsigned char ucSubType)
{
    for (int i = 0; i < _astSelfBuff.Size(); ++i)
    {
        if (_astSelfBuff[i].GetStatType() == ucStatType &&
            _astSelfBuff[i].GetSubType() == ucSubType)
        {
            return true;
        }
    }

    for (int i = 0; i < _astTeamBuff.Size(); ++i)
    {
        if (_astTeamBuff[i].GetStatType() == ucStatType &&
            _astTeamBuff[i].GetSubType() == ucSubType)
        {
            return true;
        }
    }

    for (int i = 0; i < _astEnemyBuff.Size(); ++i)
    {
        if (_astEnemyBuff[i].GetStatType() == ucStatType &&
            _astEnemyBuff[i].GetSubType() == ucSubType)
        {
            return true;
        }
    }

    return false;
}

bool CBattleBuffList::InDefinitSubBuff(unsigned char ucStatType,
        unsigned char ucSubType, int iData)
{
    for (int i = 0; i < _astSelfBuff.Size(); ++i)
    {
        if (_astSelfBuff[i].GetStatType() == ucStatType &&
            _astSelfBuff[i].GetSubType() == ucSubType &&
            _astSelfBuff[i].GetData() == iData)
        {
            return true;
        }
    }

    for (int i = 0; i < _astTeamBuff.Size(); ++i)
    {
        if (_astTeamBuff[i].GetStatType() == ucStatType &&
            _astTeamBuff[i].GetSubType() == ucSubType &&
            _astTeamBuff[i].GetData() == iData)
        {
            return true;
        }
    }

    for (int i = 0; i < _astEnemyBuff.Size(); ++i)
    {
        if (_astEnemyBuff[i].GetStatType() == ucStatType &&
            _astEnemyBuff[i].GetSubType() == ucSubType &&
            _astEnemyBuff[i].GetData() == iData)
        {
            return true;
        }
    }

    return false;
}

int CBattleBuffList::DealShieldBuff(int iRoleID, int& iChgBlood)
{
    for (int i = 0; i < _astSelfBuff.Size() && iChgBlood < 0; ++i)
    {
        if (_astSelfBuff[i].IsShield())
        {
            _astSelfBuff[i].DealShieldBuff(iRoleID, iChgBlood);

            if (_astSelfBuff[i].GetData() <= 0)
            {
                RoleDelBuffVideo(iRoleID, _astSelfBuff[i].GetID(),
                    BATTLE_BUFF_SOURCE_SELF, _astSelfBuff[i].GetSrcRoleID(), i);
                _astSelfBuff.DelOneItem(i);
            }
            break;
        }
    }

    for (int i = 0; i < _astTeamBuff.Size() && iChgBlood < 0; ++i)
    {
        if (_astTeamBuff[i].IsShield())
        {
            _astTeamBuff[i].DealShieldBuff(iRoleID, iChgBlood);

            if (_astTeamBuff[i].GetData() <= 0)
            {
                RoleDelBuffVideo(iRoleID, _astTeamBuff[i].GetID(),
                    BATTLE_BUFF_SOURCE_TEAM, _astTeamBuff[i].GetSrcRoleID(), i);
                _astTeamBuff.DelOneItem(i);
            }
            break;
        }
    }

    for (int i = 0; i < _astEnemyBuff.Size() && iChgBlood < 0; ++i)
    {
        if (_astEnemyBuff[i].IsShield())
        {
            _astEnemyBuff[i].DealShieldBuff(iRoleID, iChgBlood);

            if (_astEnemyBuff[i].GetData() <= 0)
            {
                RoleDelBuffVideo(iRoleID, _astEnemyBuff[i].GetID(),
                    BATTLE_BUFF_SOURCE_ENEMY, _astEnemyBuff[i].GetSrcRoleID(),
                    i);
                _astEnemyBuff.DelOneItem(i);
            }
            break;
        }
    }

    return 0;
}

int CBattleBuffList::DelBuffByStatType(int iRoleID, int iSrcType,
        unsigned char ucStatType, BATTLE_BUFF_LIST& stBuffList)
{
    int iRet = 0;
    int iSrcID = 0;
    unsigned int uiEffectID = 0;
    for(int i = 0; i < stBuffList.Size(); )//这里不要递增 放在了逻辑里面
    {
        if (stBuffList[i].GetStatType() == ucStatType)
        {
            iSrcID = stBuffList[i].GetSrcRoleID();
            uiEffectID = stBuffList[i].GetID();

            iRet = stBuffList.DelOneItem(i);
            if (iRet >= 0)
            {
                RoleDelBuffVideo(iRoleID, uiEffectID, iSrcType, iSrcID, iRet);
            }
        }
        else
        {
            ++i;
        }
    }

    return 0;
}

int CBattleBuffList::DelBuffByStatType(int iRoleID, unsigned char ucStatType)
{
    CT_BATTLE(("角色(%d)驱散效果(类型%d)开始",iRoleID,ucStatType));
    DumpBattleBuffList();

    DelBuffByStatType(iRoleID, BATTLE_BUFF_SOURCE_SELF, ucStatType, 
            _astSelfBuff);
    DelBuffByStatType(iRoleID, BATTLE_BUFF_SOURCE_TEAM, ucStatType,
            _astTeamBuff);
    DelBuffByStatType(iRoleID, BATTLE_BUFF_SOURCE_ENEMY, ucStatType,
            _astEnemyBuff);

    CT_BATTLE(("角色(%d)驱散效果(类型%d)结束",iRoleID,ucStatType));
    DumpBattleBuffList();

    return 0;
}

int CBattleBuffList::DelBuffBySubType(int iRoleID, int iSrcType,
        unsigned char ucStatType, unsigned char ucSubType,
        BATTLE_BUFF_LIST& stBuffList)
{
    int iRet = 0;
    int iSrcID = 0;
    unsigned int uiEffectID = 0;
    for(int i = 0; i < stBuffList.Size(); )//这里不要递增 放在了逻辑里面
    {
        if (stBuffList[i].GetStatType() == ucStatType &&
            stBuffList[i].GetSubType() == ucSubType)
        {
            iSrcID = stBuffList[i].GetSrcRoleID();
            uiEffectID = stBuffList[i].GetID();

            iRet = stBuffList.DelOneItem(i);
            if (iRet >= 0)
            {
                RoleDelBuffVideo(iRoleID, uiEffectID, iSrcType, iSrcID, iRet);
            }
        }
        else
        {
            ++i;
        }
    }

    return 0;
}

int CBattleBuffList::DelBuffBySubType(int iRoleID, unsigned char ucStatType,
        unsigned char ucSubType)
{
    CT_BATTLE(("角色(%d)驱散效果(类型%d 子类型%d)开始",
               iRoleID,ucStatType,ucSubType));
    DumpBattleBuffList();

    DelBuffBySubType(iRoleID, BATTLE_BUFF_SOURCE_SELF, ucStatType, ucSubType,
            _astSelfBuff);
    DelBuffBySubType(iRoleID, BATTLE_BUFF_SOURCE_TEAM, ucStatType, ucSubType,
            _astTeamBuff);
    DelBuffBySubType(iRoleID, BATTLE_BUFF_SOURCE_ENEMY, ucStatType, ucSubType,
            _astEnemyBuff);

    CT_BATTLE(("角色(%d)驱散子效果(类型%d 子类型%d)结束",
               iRoleID,ucStatType,ucSubType));
    DumpBattleBuffList();

    return 0;
}

int CBattleBuffList::DelAllBuff(int iRoleID, int iSrcType,
        BATTLE_BUFF_LIST& stBuffList)
{
    int iSrcID = 0;
    unsigned int uiEffectID = 0;
    for(int i = 0; i < stBuffList.Size(); ++i)
    {
        iSrcID = stBuffList[i].GetSrcRoleID();
        uiEffectID = stBuffList[i].GetID();
        RoleDelBuffVideo(iRoleID, uiEffectID, iSrcType, iSrcID, i);
    }

    stBuffList.Clear();//全部清空

    return 0;
}

void CBattleBuffList::DelAllBuff(int iRoleID)
{
    DelAllBuff(iRoleID, BATTLE_BUFF_SOURCE_SELF, _astSelfBuff);
    DelAllBuff(iRoleID, BATTLE_BUFF_SOURCE_TEAM, _astTeamBuff);
    DelAllBuff(iRoleID, BATTLE_BUFF_SOURCE_ENEMY, _astEnemyBuff);
}

void CBattleBuffList::NewTurn(int iRoleID, int iSrcType,
        BATTLE_BUFF_LIST& stBuffList)
{
    int iRet = 0;
    int iSrcID = 0;
    int iOldLastSize = 0;
    unsigned int uiEffectID = 0;
    for(int i = 0; i < stBuffList.Size(); )//这里不要递增 放在了逻辑里面
    {
        iSrcID = stBuffList[i].GetSrcRoleID();
        uiEffectID = stBuffList[i].GetID();
        iOldLastSize = stBuffList[i].GetLastSize();

        stBuffList[i].NewTurn();

        if (stBuffList[i].GetLastSize() <= 0)
        {
            iRet = stBuffList.DelOneItem(i);
            if (iRet >= 0)
            {
                RoleDelBuffVideo(iRoleID, uiEffectID, iSrcType, iSrcID, iRet);
            }
        }
        else
        {
            if (stBuffList[i].GetLastSize() != iOldLastSize)
            {
                RoleChgBuffVideo(iRoleID, uiEffectID, iSrcType, iSrcID, i);
            }

            ++i;
        }
    }
}

void CBattleBuffList::NewTurn(int iRoleID)
{
    CT_BATTLE(("角色(%d)效果结算开始",iRoleID));
    DumpBattleBuffList();

    NewTurn(iRoleID, BATTLE_BUFF_SOURCE_SELF, _astSelfBuff);
    NewTurn(iRoleID, BATTLE_BUFF_SOURCE_TEAM, _astTeamBuff);
    NewTurn(iRoleID, BATTLE_BUFF_SOURCE_ENEMY, _astEnemyBuff);

    CT_BATTLE(("角色(%d)效果结算结束",iRoleID));
    DumpBattleBuffList();
}

int CBattleBuffList::GetBuffSize()
{
    return _astSelfBuff.Size() + _astTeamBuff.Size() + _astEnemyBuff.Size();
}

CBattleBuff& CBattleBuffList::GetBattleBuff(int iIndex)
{
    int iSelfSize = _astSelfBuff.Size();
    int iTeamSize = _astTeamBuff.Size();

    if (iIndex < iSelfSize)
    {
        return _astSelfBuff[iIndex];
    }
    else if (iIndex >= iSelfSize && iIndex < (iSelfSize + iTeamSize))
    {
        return _astTeamBuff[iIndex - iSelfSize];
    }
    else
    {
        return _astEnemyBuff[iIndex - iSelfSize - iTeamSize];
    }
}

void CBattleBuffList::DumpBattleBuffList(BATTLE_BUFF_LIST& stBuffList)
{
    for (int i = 0; i < stBuffList.Size(); ++i)
    {
        stBuffList[i].DumpBattleBuff();
    }
}

void CBattleBuffList::DumpBattleBuffList()
{
    CT_BATTLE(("打印角色所属效果:"));
    if (_astSelfBuff.Size() > 0)
    {
        CT_BATTLE(("来源自身效果数量(%d)",_astSelfBuff.Size()));
        DumpBattleBuffList(_astSelfBuff);
    }
    if (_astTeamBuff.Size() > 0)
    {
        CT_BATTLE(("来源队友效果数量(%d)",_astTeamBuff.Size()));
        DumpBattleBuffList(_astTeamBuff);
    }
    if (_astEnemyBuff.Size() > 0)
    {
        CT_BATTLE(("来源敌人效果数量(%d)",_astEnemyBuff.Size()));
        DumpBattleBuffList(_astEnemyBuff);
    }
}

